#include "dominion.h"
#include "dominion_helpers.h"
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "rngs.h"

#define NOISY_TEST 0

void testCouncilRoom(){
	int player, otherPlayer, preHandCount, handCount, preOtherHandCount, otherHandCount;
	int preNumBuys, numBuys;
	int preDeckCount, deckCount;
	int prePlayedCount, playedCount;
	int seed = 50;
	int numPlayer = 3;
	struct gameState state;
	int cur, it;
	int k[10] = {adventurer, council_room, feast, gardens, mine,
					remodel, smithy, village, baron, great_hall};


	// set choices to playDom example
	int choice1 = 0, choice2 = 0, choice3 = 0, handPos = 0, bonus=0;

	for(player = 0; player < numPlayer; player++){
		// clear game state
		memset(&state, 23, sizeof(struct gameState));
	    // initialize game
		int r = initializeGame(numPlayer, k, seed, &state);
		if(r < 0){
     		printf("Error initializing game...\n");
		}
		// set the players turn
		state.whoseTurn = player;
		// compensate for initializeGame where other players don't draw their cards
		if(player > 0){
        	for(it = 0; it < 5; it++){
             	drawCard(state.whoseTurn, &state);
			}
		}

		// verify empty hand
		if(state.handCount[player] == 0){
#if (NOISY_TEST == 1)
			printf("Checking Player 0's handcount: %d\n", state.handCount[0]);
#endif
         	state.handCount[player] = 1;
#if (NOISY_TEST == 1)
			printf("Player %d handcount was empty, new handcount: %d\n", player, state.handCount[player]);
#endif
		}

		// force council room card to be the first card in hand
		state.hand[player][0] = council_room;		

		// Obtain precondition for other players - assume only 1 player can be checked
		if(player == 0){ // checks the 2nd player if the first player is under test
        	otherPlayer = 1;
		}else{ // always checks the first player when its any other players turn
            otherPlayer = 0;
		}

		// Determine preconditions
		preHandCount = state.handCount[player];
		preOtherHandCount = state.handCount[otherPlayer];
		preNumBuys = state.numBuys;
		preDeckCount = state.deckCount[player];
		prePlayedCount = state.playedCardCount; // discard pile

		// Precondition continued... verify 3 cards from deck
		int drawCard1 = state.deck[player][preDeckCount - 1];
		int drawCard2 = state.deck[player][preDeckCount - 2];
		int drawCard3 = state.deck[player][preDeckCount - 3];

		cur = cardEffect(council_room, choice1, choice2, choice3, &state, handPos, &bonus);
        if(cur != 0){
        	printf("ERROR: Council Room card could not be used.\n");
			break;
		}                                                        
		// obtain postconditions
		handCount = state.handCount[player];
		otherHandCount = state.handCount[otherPlayer];
		numBuys = state.numBuys;
		deckCount = state.deckCount[player];
		playedCount = state.playedCardCount;

		// Postcondition continued... verify 3 cards from deck are in hand
        int handCard1 = state.hand[player][handCount - 3];
		int handCard2 = state.hand[player][handCount - 2];
		int handCard3 = state.hand[player][handCount - 1];
#if (NOISY_TEST == 1)
		printf("Player %d Card #1: Expected: %d. Actual: %d\n", player, drawCard1, handCard1);
#endif
		assert(drawCard1 == handCard1); // verifies 1st drawn card is the 3rd hand card from last
#if (NOISY_TEST == 1)
		printf("Player %d Card #2: Expected: %d. Actual: %d\n", player, drawCard2, handCard2);
#endif
		assert(drawCard2 == handCard2); // verifies 2nd drawn card is the 2nd hand card from last
#if (NOISY_TEST == 1)
		printf("Player %d Card #3: Expected: %d. Actual: %d\n", player, drawCard3, handCard3);
#endif
		assert(drawCard3 == handCard3); // verifies 3rd drawn card is the last hand card
		
		// Asserts and Prints
#if (NOISY_TEST == 1)
		printf("Player %d Hand count - Before: %d. Expected: %d. Actual: %d\n", player, preHandCount, preHandCount + 3, handCount);
#endif
		assert(preHandCount + 3 == handCount); // verifies +4 cards were drawn & 1 discarded
#if (NOISY_TEST == 1)
		printf("Other Player %d Hand count - Before: %d. Expected: %d. Actual: %d\n", otherPlayer, preOtherHandCount, preOtherHandCount + 1, otherHandCount);
#endif
		assert(preOtherHandCount + 1 == otherHandCount); // verifies other player drew a card
#if (NOISY_TEST == 1)
		printf("Player %d Number of Buys - Before: %d. Expected: %d. Actual: %d\n", player, preNumBuys, preNumBuys + 1, numBuys);
#endif
		assert(preNumBuys + 1 == numBuys); // verifies +1 buy
#if (NOISY_TEST == 1)
		printf("Player %d Deck count - Before: %d. After: %d\n", player, preDeckCount, deckCount);
#endif
		assert(preDeckCount - 4 == deckCount); // verifies 4 cards were taken from deck
#if (NOISY_TEST == 1)
		printf("Player %d Played count - Before: %d. After: %d\n", player, prePlayedCount, playedCount);
#endif
		assert(prePlayedCount + 1 == playedCount); // verifies discarding a played card to played count

	}
	printf("Finishing testCouncilRoom()\n");
}

int main(){
	testCouncilRoom();
	return 0;
}
